"""String utilities"""

import re
from os.path import basename, dirname
from typing import List

from loguru import logger


def remove_ansi_escape_sequences(text: str):
    """Remove ANSI escape sequences from a string"""

    ansi_escape_pattern = re.compile(r"\x1B\[[0-?9;]*[mK]")
    return ansi_escape_pattern.sub("", text)


def extract_path_from_error(error_message: str):
    """Extract the path from an error message

    The error is like:
    error: /a/b/c: No such file or directory
    """

    return error_message.split(":")[1].strip()


def extract_paths_not_found(error_lines: List[str]):
    """Iterate over all the errors and extract the paths that are not found"""

    if not error_lines:
        return []

    _not_found_files = []
    for line in error_lines:
        line = line.strip()
        line = remove_ansi_escape_sequences(line)
        if line.startswith("error:") and line.endswith("No such file or directory"):
            extracted_path = extract_path_from_error(error_message=line)
            extracted_path = extracted_path.rstrip(":")
            _not_found_files.append(extracted_path)

    if _not_found_files:
        logger.warning(
            f"The following files are not found: {', '.join(_not_found_files)}"
        )
        return _not_found_files

    logger.success("No errors were encountered")
    return []


def get_build_number_from(profraw_file_path: str) -> str:
    """Get the build number from the profraw file path

    The build number is the name of the directory that contains the profraw file

    Args:
    profraw_file_path (str): The profraw file path, e.g. /a/b/c/r.profraw

    Returns:
    str: The build number
    """

    profraw_file_path = profraw_file_path.rstrip("/")
    build_number_dir = dirname(profraw_file_path)
    build_number = basename(build_number_dir)
    return build_number


def parse_device_profraw_file_name(file_name: str):
    """Parse the profraw file name to get the device id and the macho file name

    Args:
    file_name (str): The profraw file name, e.g. deviceid_machoname.profraw

    Returns:
    tuple: The device id and the macho file name
    """

    if not file_name.endswith(".profraw"):
        logger.error(f"Invalid file name: {file_name}, it should end with '.profraw'")
        raise ValueError

    # Get the id of the device and the name of the macho file
    name_parts = file_name.split("_")
    if len(name_parts) < 2:
        logger.error(
            f"Invalid file name: {file_name}, it should contain at least two parts separated by '_'"
        )
        raise ValueError

    device_id = name_parts[0]
    name_without_device_id = name_parts[1]
    macho_file_name = name_without_device_id.replace(".profraw", "")

    return device_id, macho_file_name


def get_replaced_branch_name(branch_name: str):
    """Replace the branch name with the new one

    Args:
    branch_name (str): The original branch name

    Returns:
    str: The replaced branch name
    """

    return branch_name.replace("/", "_")
